<template>
    <div class="pms_category">
        <el-card>
            <template #header>
                <el-button icon="Plus" @click="handleAddFirst">添加一级分类</el-button>
            </template>
            <el-tree v-loading="loading" :data="pmsCategoryTree" :props="defaultProps" draggable
                :allow-drop="handleAllowDrop" @node-drop="handleNodeDrop" node-key="catId"
                :default-expanded-keys="defaultExpandedKeys" :accordion="true">
                <template #default="{ node, data }">
                    <div class="inner">
                        <span>{{ node.label }}</span>
                        <div>
                            <el-button icon="Edit" @click.stop="handleEdit(node, data)">编辑</el-button>
                            <el-button v-if="data.catLevel !== 3" icon="Plus"
                                @click.stop="handleAddNext(data)">添加下级分类</el-button>
                            <el-button v-else type="danger" icon="Delete"
                                @click.stop="handleDelete(data)">删除</el-button>
                        </div>
                    </div>
                </template>
            </el-tree>
        </el-card>
        <el-dialog :title="categoryFormData.isEdit ? '编辑分类' : '添加分类'" v-model="dialogVisible"
            :close-on-click-modal="false">
            <AddOrEditPmsCategory v-if="dialogVisible" :categoryFormData="categoryFormData" @success="onSuccess">
            </AddOrEditPmsCategory>
        </el-dialog>
    </div>
</template>

<script setup lang="ts" name="PmsCategory">
import { ref } from 'vue'
import { pmsCategoryListTree, pmsCategoryRemove } from '@/api/mall/pmsCategory';
import { onMounted } from 'vue';
import type { pmsCategorySortType, pmsCategoryType } from '@/api/mall/pmsCategory/types';
import type { RenderContentContext } from 'element-plus'
import AddOrEditPmsCategory from './components/AddOrEditPmsCategory.vue';

let pmsCategoryTree = ref<pmsCategoryType[]>()
const loading = ref(false)
const defaultExpandedKeys = ref()
type Node = RenderContentContext['node']
type Data = RenderContentContext['data']

const defaultProps = {
    children: 'children',
    label: 'name',
}

onMounted(() => {
    loadPmsCategoryTree();
})

const loadPmsCategoryTree = async () => {
    try {
        loading.value = true
        const data = await pmsCategoryListTree()
        if (data.code === 200) {
            pmsCategoryTree.value = data.data
        }
    } finally {
        loading.value = false
    }
}

// ---------- 添加/编辑/删除 ----------
import { ElMessage, ElMessageBox } from 'element-plus';
const dialogVisible = ref(false)
const categoryFormData = reactive({ isEdit: false, catId: 0, parentCid: 0, name: '', catLevel: 0 })

const handleAddFirst = () => {
    categoryFormData.isEdit = false
    categoryFormData.parentCid = 0
    categoryFormData.catLevel = 1
    dialogVisible.value = true
}

const handleAddNext = (data: Data) => {
    categoryFormData.isEdit = false
    categoryFormData.parentCid = data.catId
    categoryFormData.name = data.name
    categoryFormData.catLevel = data.catLevel + 1
    dialogVisible.value = true
}

const handleEdit = (_node: Node, data: Data) => {
    categoryFormData.isEdit = true
    categoryFormData.parentCid = data.parentCid
    categoryFormData.catId = data.catId
    dialogVisible.value = true
}

const handleDelete = (category: Data) => {
    ElMessageBox.confirm(`确认删除分类【${category.name}】吗?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
    }).then(async () => {
        const data = await pmsCategoryRemove(category.catId)
        if (data.code === 200) {
            ElMessage.success('删除成功');
            loadPmsCategoryTree();
            defaultExpandedKeys.value = [categoryFormData.parentCid]
        } else {
            ElMessage.error('删除失败');
        }
    });
}

const onSuccess = () => {
    dialogVisible.value = false
    loadPmsCategoryTree()
    defaultExpandedKeys.value = [categoryFormData.parentCid]
}

// ---------- 分类树的拖动 ----------
import type { AllowDropType, NodeDropType } from 'element-plus'
import type { DragEvents } from 'element-plus/es/components/tree/src/model/useDragNode'
import { reactive } from 'vue';
import { pmsCategoryUpdateSort } from '@/api/mall/pmsCategory';

/**
 * 是否允许拖拽
 * @param draggingNode 正在拖拽的节点
 * @param dropNode 放置的目标节点
 * @param type 放置在目标节点的哪个位置:prev（同级前）、inner（内）、next（同级后）
 */
const handleAllowDrop = (draggingNode: Node, dropNode: Node, type: AllowDropType) => {
    return type !== 'inner' && draggingNode.data.parentCid === dropNode.data.parentCid
}

/**
 * 拖拽成功完成时触发的事件
 * @param draggingNode 被拖拽节点对应的 Node
 * @param dropNode 结束拖拽时最后进入的节点
 * @param dropType 放置在目标节点的哪个位置:prev（同级前）、inner（内）、next（同级后）
 * @param event 
 */
const handleNodeDrop = (draggingNode: Node, dropNode: Node, _dropType: NodeDropType, _event: DragEvents) => {
    // 拿到 sort 然后交换顺序
    updateSort(draggingNode, dropNode)
}

const updateSort = async (draggingNode: Node, dropNode: Node) => {
    try {
        loading.value = true
        const pmsCategorySort: pmsCategorySortType = {
            lastCatId: draggingNode.data.catId,
            lastSort: draggingNode.data.sort,
            nextCatId: dropNode.data.catId,
            nextSort: dropNode.data.sort
        }
        const data = await pmsCategoryUpdateSort(pmsCategorySort)
        if (data.code === 200) {
            loadPmsCategoryTree()
            defaultExpandedKeys.value = [draggingNode.data.parentCid]
        }
    } finally {
        loading.value = false
    }
}
</script>

<style scoped lang="scss">
.inner {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px;
    border-bottom: 1px solid #ebeef5;

    >span:first-of-type {
        display: flex;
        align-items: center;
    }

    .el-input {
        margin-left: 10px;
    }
}

:deep() {
    .el-tree-node__content {
        height: auto;
    }
}
</style>